﻿using System;
using System.Collections.Generic;
using System.Linq;

namespace We.Moonlight
{
    public struct KeyValueTriplet<TK, TV1, TV2>
    {
        private TK _key;
        private TV1 _value1;
        private TV2 _value2;
        public KeyValueTriplet(TK Key, TV1 Value1, TV2 Value2)
        {
            _key = Key;
            _value1 = Value1;
            _value2 = Value2;
        }
        public TK Key
        {
            get { return _key; }
        }
        public TV1 Value1
        {
            get { return _value1; }
            set { _value1 = value; }
        }
        public TV2 Value2
        {
            get { return _value2; }
            set { _value2 = value; }
        }
    }
    public struct KeyValueQuadruplet<TK, TV1, TV2, TV3>
    {
        private TK _key;
        private TV1 _value1;
        private TV2 _value2;
        private TV3 _value3;
        public KeyValueQuadruplet(TK Key, TV1 Value1, TV2 Value2, TV3 Value3)
        {
            _key = Key;
            _value1 = Value1;
            _value2 = Value2;
            _value3 = Value3;
        }
        public TK Key
        {
            get { return _key; }
        }
        public TV1 Value1
        {
            get { return _value1; }
            set { _value1 = value; }
        }
        public TV2 Value2
        {
            get { return _value2; }
            set { _value2 = value; }
        }
        public TV3 Value3
        {
            get { return _value3; }
            set { _value3 = value; }
        }
    }
    public static class FileAssoc
    {

        private static List<KeyValueQuadruplet<string, ShellType, string, FilePreviewMethod>> Dict = new List<KeyValueQuadruplet<string, ShellType, string, FilePreviewMethod>>();

        public static void AddValue(string Extension, ShellType ShellType, string ShellInfo, FilePreviewMethod PM)
        {
            if (!Dict.Where(n => n.Key.Equals(Extension)).Any())
            {
                FTA.Insert(Extension, (int)ShellType, ShellInfo, (int)PM);
                Dict.Add(new KeyValueQuadruplet<string, ShellType, string, FilePreviewMethod>(Extension, ShellType, ShellInfo, PM));
            }
            else
            {
                throw new ArgumentException("An Entry with the same Extension Exists.");
            }
        }
        /// <summary>
        /// Returns a KeyValueQuadruplet (Extension, Shell Type, Shell Info, Preview Method) for an Extension.
        /// </summary>
        /// <param name="E">the Extension</param>
        /// <returns>KVQ(Extension, Shell Type, Shell Info, Preview Method)</returns>
        /// <exception>ArgumentNullException when no Assocuation Exists</exception>
        public static KeyValueQuadruplet<string, ShellType, string, FilePreviewMethod> RetrieveValue(string E)
        {
            E = E.ToUpper();
            try
            {
                return new KeyValueQuadruplet<string, ShellType, string, FilePreviewMethod>(E, Dict.Where(n => n.Key == E).First().Value1, Dict.Where(n => n.Key == E).First().Value2, Dict.Where(n => n.Key == E).First().Value3);
            }
            catch (InvalidOperationException IOX)
            {
                throw new ArgumentNullException("No Association Exists for this Extension.", IOX);
            }
        }
        public static void UpdateValue(string OldExt, string NewExt, ShellType ST, string SI, FilePreviewMethod PM)
        {
            FTA.Update(NewExt, (int)ST, SI, (int)PM, OldExt);
            Fill();
        }
        public static void Delete(string Ext)
        {
            FTA.Delete(Ext);
            Fill();
        }

        private static mDBTableAdapters.FileAssociationTableAdapter FTA = new We.Moonlight.mDBTableAdapters.FileAssociationTableAdapter();

        public static void Fill()
        {
            Dict.Clear();
            foreach (mDB.FileAssociationRow DR in FTA.GetData().Rows)
            {
                Dict.Add(new KeyValueQuadruplet<string, ShellType, string, FilePreviewMethod>(DR.Ext, (ShellType)DR.SType, DR.SInfo, (FilePreviewMethod)DR.PreviewMeth));
            }
        }
    }
}